﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Project1
{
    /// <summary>
    /// An object that is drawn on the screen and which keeps track of its
    /// position and size
    /// </summary>
    public class BoundedObject : DrawableGameComponent
    {
        Texture2D _sprite;
        string _asset;

        public BoundedObject(Game1 g, string asset, Vector2 position)
            : base(g)
        {
            Position = position;
            _asset = asset;
        }

        public Vector2 Position { get; set; }
        public Vector2 Size { get; private set; }

        public Rectangle BoundingRect
        {
            get {
                return new Rectangle((int)(Position.X - Size.X / 2.0f), 
                                     (int)(Position.Y - Size.Y / 2.0f),
                                     (int)Size.X, (int)Size.Y); }
        }

        public override void Draw(GameTime gameTime)
        {
            var _game = Game as Game1;
            _game.SpriteBatch.Draw(_sprite, GetScreenRect(), Color.White);

            base.Draw(gameTime);
        }

        /// <summary>
        /// Do something if a player ran into us.  Or don't.
        /// Returns whether this object should be destroyed
        /// </summary>
        public virtual bool OnPlayerCollide(Player p) { return false; }

        protected override void LoadContent()
        {
            _sprite = Game.Content.Load<Texture2D>(_asset);
            Size = new Vector2(_sprite.Width, _sprite.Height);
            base.LoadContent();
        }

        Rectangle GetScreenRect()
        {
            var _game = Game as Game1;
            return new Rectangle(BoundingRect.Left,
                                 _game.ScreenHeight - BoundingRect.Bottom,
                                 BoundingRect.Width,
                                 BoundingRect.Height);
        }
    }

    /// <summary>
    /// Represents a platform block
    /// </summary>
    class Block : BoundedObject
    {
        private const string ASSET_NAME = "plainblock";
        public Block(Game1 g, Vector2 position) : base(g, ASSET_NAME, position) { }

        public override bool OnPlayerCollide(Player p)
        {
            if (p.BoundingRect.Bottom > BoundingRect.Top)
            {
                // Player lands on a block, just stop motion.
                p.OnGround = true;
            }
            return false;
        }
    }

    class MiniBlock : BoundedObject
    {
        private const string ASSET_NAME = "miniblock";
        public MiniBlock(Game1 g, Vector2 position) : base(g, ASSET_NAME, position) { }

        public override bool OnPlayerCollide(Player p)
        {
            if (p.BoundingRect.Bottom > BoundingRect.Top)
            {
                // Player lands on a block, just stop motion.
                p.OnGround = true;
            }
            return false;
        }
    }

    /// <summary>
    /// Represents a "back-to-the-start" portal
    /// </summary>
    class Portal : BoundedObject
    {
        const string ASSET_NAME = "portal";
        public Portal(Game1 g, Vector2 position) : base(g, ASSET_NAME, position) { }

        public override bool OnPlayerCollide(Player p)
        {
            var _game = Game as Game1;
            // Player hits the portal, 
            p.Position = _game.PlayerStart;
            return false;
        }
    }
    class gkey : BoundedObject
    {
        const string ASSET_NAME = "key";
        public gkey(Game1 g, Vector2 position) : base(g, ASSET_NAME, position) { }

        public override bool OnPlayerCollide(Player p)
        {
            var _game = Game as Game1;
            // Player gets the key, 
            _game.Exit();
            return true;
        }
    }
    class cop : BoundedObject
    {
        const string ASSET_NAME = "man";
        public cop(Game1 g, Vector2 position) : base(g, ASSET_NAME, position) { }

        public override bool OnPlayerCollide(Player p)
        {
            var _game = Game as Game1;
            // Player touches cop
            if (_game.cash >= 0)
                _game.cash -= 10;
            else
                _game.cash = 0;
            p.Position = _game.PlayerStart;
            return false;
        }
    }
}